#include "stdafx.h"
#include "SingleThread.h"

namespace COMMONLIB
{

	SingleThread::SingleThread():m_hThread(NULL),m_dwThreadID(0)
	{
	}

	SingleThread::~SingleThread()
	{
		WaitAndForceExit(0);
	}

	BOOL SingleThread::CreateThread()
	{
		if (m_hThread != NULL)
		{
			return FALSE;
		}

		THREAD_PARAM param;
		param.p = this;
		param.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		m_hThread = (HANDLE)_beginthreadex(NULL, NULL, __ThreadProc, &param, NULL, (unsigned*)&m_dwThreadID);
		if (m_hThread != NULL)
		{
			WaitForSingleObject(param.hEvent, INFINITE);
			return TRUE;
		}
		return FALSE;
	}
	void SingleThread::Exit(DWORD dwWaitTime)
	{
		NotifyExit();
		WaitAndForceExit(dwWaitTime);
	}

	UINT WINAPI SingleThread::__ThreadProc(LPVOID lpParam)
	{
		THREAD_PARAM* pInfo = (THREAD_PARAM*)lpParam;
		if (pInfo != NULL)
		{
			SingleThread* pSite = (SingleThread*)pInfo->p;
			HANDLE hEvent = pInfo->hEvent;

			MSG msg;
			::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);

			SetEvent(hEvent);
			if (pSite != NULL)
			{
				return pSite->DoThreadWork();
			}		
		}
		return 0;
	}

	void SingleThread::WaitAndForceExit(DWORD dwWait)
	{
		if (m_hThread != NULL)
		{
			DWORD dwRet = WaitForSingleObject(m_hThread, dwWait);
			if (dwRet == WAIT_TIMEOUT)
			{
				TerminateThread(m_hThread, 0);
			}
			CloseHandle(m_hThread);
			m_hThread = NULL;
		}
	}
	
	void SingleThread::PostThreadMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		::PostThreadMessage(m_dwThreadID, uMsg, wParam, lParam);
	}
}